package example04;

import java.util.Iterator;
import net.sf.jeppers.grid.*;

/**
 * @author grom
 */
public class DemoSpanModel extends AbstractSpanModel {
	private GridModel gridModel;
	
	public DemoSpanModel(GridModel gridModel) {
		this.gridModel = gridModel;
	}
	
	public Iterator getSpanIterator() {
		return new SpanIterator(gridModel, this);
	}
	
    public CellSpan getSpanOver(int row, int column) {
        if ((row % 3) != 0 && (column % 3) != 0) {
            return new CellSpan(
                row - (row % 3) + 1,
                column - (column % 3) + 1,
                2,
                2);
        }
        return new CellSpan(row, column, 1, 1);
    }
	
    public boolean isCellSpan(int row, int column) {
		if ((row % 3) != 0 && (column % 3) != 0) {
        	return true;
        }
        return false;
    }
    
    private static class SpanIterator implements Iterator {
    	private GridModel gridModel;
    	private SpanModel spanModel;
    	private boolean hasNext = true;
    	private int row = 0;
    	private int column = -1;
    	
        public SpanIterator(GridModel gridModel, SpanModel spanModel) {
            this.gridModel = gridModel; 
            this.spanModel = spanModel;           
        }
    	
    	public boolean hasNext() { 
			findNext();
			if (column >= gridModel.getColumnCount()
				&& row >= gridModel.getRowCount()) {
				hasNext = false;
			}				  		
    		return hasNext;
    	}
    	
    	private void findNext() {
    		if (! hasNext) {
    			return;
    		}
			if (column < gridModel.getColumnCount()) {
				column++;
			}
			if (column == gridModel.getColumnCount()) {
				column = 0;
				row++;
			}
            if (column >= gridModel.getColumnCount()
                || row >= gridModel.getRowCount()) {
                // out of bounds
                hasNext = false;
                return;
            }
			CellSpan span = spanModel.getSpanOver(row, column);
            if (span.getRow() != row
                || span.getColumn() != column
                || (span.getRowCount() <= 1 && span.getColumnCount() <= 1)) {
                findNext(); // look for next span                
            }
    	}
    	
    	public Object next() {
			return spanModel.getSpanOver(row, column);
    	}
    	
    	public void remove() {
    		// ignore
    	}
    }
}
